using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.DataAccess.Common;
using T.FAS.Runtime.DataAccess.Kernel;
using T.FAS.Runtime.DataAccess.SPI;
using T.FAS.Runtime.DataAccess.SQLDom;
using T.FAS.Runtime.Metadata.Entity.DataModel;

namespace T.FAS.Runtime.DataAccess.Engine
{
    class DODeleteService : IDeleteService<DataObject>
    {
        public event ExecuteDataAccessAction Execute;
        public event BuildDataAccessActionContext BuildContext;

        /// <summary>
        /// 删除指定的数据
        /// </summary>
        /// <remarks>按主键数据作为删除依据</remarks>
        /// <param name="metaData">领域模型</param>        
        /// <param name="dataID">主键数据</param>        
        /// <returns>删除SQL</returns>
        public void DeleteByID(DataObject metaData, string dataID, Dictionary<string, object> exrParams = null)
        {
            if (metaData == null)
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_MetaDataCannotBeNull);
            if (string.IsNullOrWhiteSpace(dataID))
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_DataIDCannotBeNull);

            var cdo = CDOConverter.Convert(metaData);
            var sqls = SQLBuilderFactory.CreateCDOSQLBuilder().ParseDeleteSqlByID(cdo, dataID);

            var db = DatabaseFactory.CreateDefaultDatabase();
            db.ExecuteSQLWithTransaction(sqls);
        }

        /// <summary>
        /// 批量删除指定的数据
        /// </summary>
        /// <remarks>按主键数据作为删除依据</remarks>
        /// <param name="metaData">领域模型</param>        
        /// <param name="dataID">主键数据</param>        
        /// <returns>删除SQL</returns>
        public void DeleteByIDList(DataObject metaData, IEnumerable<string> dataIDs, Dictionary<string, object> exrParams = null)
        {
            if (metaData == null)
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_MetaDataCannotBeNull);
            if (dataIDs == null || dataIDs.Count() == 0)
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_DataIDCannotBeNull);

            var cdo = CDOConverter.Convert(metaData);
            var sqlList = new SqlStatementCollection();
            foreach (var dataID in dataIDs)
            {
                var sqls = SQLBuilderFactory.CreateCDOSQLBuilder().ParseDeleteSqlByID(cdo, dataID);
                sqlList.AddRange(sqls);
            }

            var db = DatabaseFactory.CreateDefaultDatabase();
            db.ExecuteSQLWithTransaction(sqlList);
        }

        /// <summary>
        /// 删除指定的数据
        /// </summary>
        /// <remarks>按主键数据作为删除依据</remarks>
        /// <param name="metaData">领域模型</param> 
        /// <param name="cnoId">领域对象</param>
        /// <param name="dataID">主键数据</param>           
        public void DeleteByID(DataObject metaData, string cnoId, string dataID, Dictionary<string, object> exrParams = null)
        {
            if (metaData == null)
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_MetaDataCannotBeNull);
            if (string.IsNullOrWhiteSpace(cnoId))
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_CNOIDCannotBeNull);
            if (string.IsNullOrWhiteSpace(dataID))
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_DataIDCannotBeNull);

            var cdo = CDOConverter.Convert(metaData);
            var cno = cdo.CompositeNodeObjects.FirstOrDefault(i => i.ID == cnoId);
            if (cno == null)
            {
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.CDOService_CannotFindCNOInstance + cnoId);
            }

            var sqls = SQLBuilderFactory.CreateCDOSQLBuilder().ParseDeleteSqlByID(cdo, cno, dataID);

            var db = DatabaseFactory.CreateDefaultDatabase();
            db.ExecuteSQLWithTransaction(sqls);
        }

        /// <summary>
        /// 批量删除指定的数据
        /// </summary>
        /// <remarks>按主键数据作为删除依据</remarks>
        /// <param name="metaData">领域模型</param> 
        /// <param name="cnoId">领域对象</param>
        /// <param name="dataID">主键数据</param>                
        public void DeleteByIDList(DataObject metaData, string cnoId, IEnumerable<string> dataIDs, Dictionary<string, object> exrParams = null)
        {
            if (metaData == null)
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_MetaDataCannotBeNull);
            if (string.IsNullOrWhiteSpace(cnoId))
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_CNOIDCannotBeNull);
            if (dataIDs == null || dataIDs.Count() == 0)
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.DataModelService_DataIDCannotBeNull);
            
            var cdo = CDOConverter.Convert(metaData);
            var cno = cdo.CompositeNodeObjects.FirstOrDefault(i => i.ID == cnoId);
            if (cno == null)
            {
                throw new FasException(DataAccessErrorCode.CompositeDataObject.NullValue, CommonStringClassEngine.CDOService_CannotFindCNOInstance + cnoId);
            }

            var sqlList = new SqlStatementCollection();
            foreach (var dataID in dataIDs)
            {
                var sqls = SQLBuilderFactory.CreateCDOSQLBuilder().ParseDeleteSqlByID(cdo, cno, dataID);
                sqlList.AddRange(sqls);
            }

            var db = DatabaseFactory.CreateDefaultDatabase();
            db.ExecuteSQLWithTransaction(sqlList);
        }
    }
}
